package com.wechat.server.mp.controller;


import com.wechat.server.mp.common.domain.UnionUser;
import com.wechat.server.mp.common.domain.User;
import com.wechat.server.mp.common.dto.UserDto;
import com.wechat.server.mp.common.exception.HasSignException;
import com.wechat.server.mp.common.exception.LotteryException;
import com.wechat.server.mp.common.exception.NotStartException;
import com.wechat.server.mp.common.exception.ServerInternalException;
import com.wechat.server.mp.common.exception.VoteException;
import com.wechat.server.mp.config.WechatConfigProperties;
import com.wechat.server.mp.service.UserService;
import com.wechat.server.mp.util.ErrorEnum;
import com.wechat.server.mp.util.ImageUtil;
import com.wechat.server.mp.util.R;
import com.wechat.server.mp.util.YiDongUtil;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author andy
 * @date 2016/12/20
 */
@RequestMapping("user")
@RestController
@Slf4j
@RequiredArgsConstructor
public class UserController {
    private final UserService userService;
    private final StringRedisTemplate stringRedisTemplate;
    private final WechatConfigProperties properties;

    /**
     * 保存签到信息
     *
     * @param u
     * @return
     */
    @RequestMapping(value = "/save", method = RequestMethod.POST)
    public R save(@RequestBody @Valid User u, BindingResult bindingResult) throws HasSignException, WxErrorException, VoteException, ServerInternalException, NotStartException {
        if (bindingResult.hasErrors()) {
            return R.error(Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage());
        }
        if (u.getName().length() > 30) {
            return R.error("姓名不超过30字符");
        }
        if (StringUtils.isBlank(u.getOpenId())) {
            return R.error();
        }
        userService.save(u);
        return R.ok();

    }

    /**
     * 获取签到信息
     *
     * @param openId
     * @return
     */
    @SneakyThrows
    @RequestMapping(value = "/getUser", method = RequestMethod.GET)
    public R get(@RequestParam(value = "id") String openId) {
        return R.ok().put("msg", userService.get(openId));
    }

    /**
     * 判断是否签到
     *
     * @param openId
     * @return
     */
    @RequestMapping(value = "/isMember", method = RequestMethod.GET)
    public R isMember(@RequestParam(value = "id") String openId) throws ServerInternalException, NotStartException {

        if (!properties.signTime()) {
            log.info("签到时间为：{} ~ {}", properties.getSinOpenTime(), properties.getSignCloseTime());
            return R.error(ErrorEnum.NOT_START.getCode(), properties.getSignCloseTime());
        }
        if (userService.isMember(openId)) {
            final User user = userService.get(openId);
            UserDto userDto = new UserDto();
            BeanUtils.copyProperties(user, userDto);
            return R.ok().put("code",ErrorEnum.HAS_SIGN.getCode()).put("data",userDto);
        } else {
            return R.ok().put("code", ErrorEnum.NOT_SIGN.getCode());
        }

    }

    /**
     * 获取签到用户信息
     *
     * @return
     */
    @RequestMapping(value = "/userList", method = RequestMethod.GET)
    public R getRandomUserList(Integer count) throws NotStartException, ServerInternalException {

        if (null == count) {
            count = 100;
        }
        return R.ok().put("data", userService.randomUsers(count));

    }

    @Deprecated
    @RequestMapping(value = "/submitLottery", method = RequestMethod.POST)
    public R confirmLucky(@RequestBody List<String> openIds) throws ServerInternalException, NotStartException {
        List<UnionUser> onlyUsers = new ArrayList<>();

        for (String openId : openIds) {
            UnionUser onlyUser = userService.get(openId);
            onlyUsers.add(onlyUser);
        }
        userService.commitLotteryPerson(onlyUsers);

        return R.ok().put(ErrorEnum.SUCCESS.getDescription(), ErrorEnum.SUCCESS.getCode());
    }

    /**
     * 抽奖，返回一个中奖者信息
     *
     * @return
     */
    @RequestMapping(value = "/lotterySelect", method = RequestMethod.GET)
    public R lotterySelect() throws LotteryException, ServerInternalException, NotStartException {

        return R.ok().put("data", (userService.randomUser(1)));

    }

    /**
     * 抽奖，返回多个中奖者信息
     *
     * @param count
     * @return
     */
    @RequestMapping(value = "/lotteryUserList", method = RequestMethod.GET)
    public R LotteryUser(@RequestParam Integer count) throws LotteryException, ServerInternalException, NotStartException {

        return R.ok().put("data", userService.randomUser(count));

    }

    /**
     * @param index 22号上午index=0，下午index=1；23号上午index=2,下午index=3，晚上index=4
     * @return
     */
    @RequestMapping(value = "/allUserList", method = RequestMethod.GET)
    public R getUserList(Integer index) throws NotStartException, ServerInternalException {

        if (null != index) {
            if (index > 4) {
                log.error("列表不存在");
                return R.error("列表不存在");
            }
            return R.ok().put("data", userService.orderMealUserCountAndUserList());
        }
        return R.ok().put("data", userService.orderMealUserCountAndUserList());

    }

    /**
     * 返回签到者数量
     *
     * @return
     */
    @RequestMapping(value = "/userListCount", method = RequestMethod.GET)
    public R getUserListCount() throws ServerInternalException, NotStartException {

        return R.ok().put("data", userService.getUserSize());

    }

    /**
     * 获取中奖名单
     *
     * @param degree 0：一等奖；1：二等奖；2：三等奖 -1:所有
     * @return
     */
    @RequestMapping(value = "/luckyUserList", method = RequestMethod.GET)
    public R getLuckyUserList(Integer degree) throws NotStartException, ServerInternalException {

        if (null != degree) {
            if (degree == -1) {
                return R.ok().put("data", userService.getAllMessage());
            } else {
                return R.ok().put("data", userService.getMessageByDegree(degree));
            }
        }
        return R.ok().put("data", userService.getAllMessage());

    }

    /**
     * 返回头像image
     *
     * @param url
     * @param response
     */
    @RequestMapping(value = "/headImgUrl", method = RequestMethod.GET)
    public void getHeadImgUrl(@RequestParam String url, HttpServletResponse response) throws IOException {
        // TODO 前端自己画圆角头像，不需要再通过服务端进行处理
        response.setContentType("image/jpeg");
        System.setProperty("java.awt.headless", "true");
        if (StringUtils.isBlank(url)) {
            return;
        }

        ServletOutputStream outputStream = response.getOutputStream();
        ImageUtil.toPNG(new URL(url), outputStream, 250, 250, stringRedisTemplate);

    }

    /**
     * 获取未中奖者的数量
     *
     * @return
     */
    @RequestMapping(value = "/unHitUserSize", method = RequestMethod.GET)
    public R getNotLuckyUserSize() throws ServerInternalException, NotStartException {
        Long userSize = userService.getUserSize();
        Long luckySetSize = userService.getLuckySetSize();
        long l = userSize - luckySetSize;
        return R.ok().put("data", l);

    }
    @RequestMapping(value = "/yidong", method = RequestMethod.GET)
    public R yidong(String fileName) throws Exception {
        List<String> list = YiDongUtil.gmFileDencrypt("/root/downfile", fileName, "bbfbb756fff83e597fee36939f9276f65abe2456d7bfa40cfbfaafcbd7b47529");
        log.error("获取的数据 {}", list);
        return R.ok().put("data", "l");

    }

    @PostMapping(value = "/yidongV2")
    public R yidongV2(@RequestBody YiDongDTO dto) throws Exception {
        List<String> list = YiDongUtil.gmFileDencrypt(dto.getPath(), dto.getFileName(), "bbfbb756fff83e597fee36939f9276f65abe2456d7bfa40cfbfaafcbd7b47529");
        log.error("获取的数据 {}", list);
        return R.ok().put("data", "l");

    }


    @PostMapping(value = "/yidongFTP")
    public R yidongFTP(@RequestBody YiDongDTO dto) throws Exception {
        List<String> list = YiDongUtil.gmFileDencryptSftp(dto.getPath(), dto.getFileName(), "bbfbb756fff83e597fee36939f9276f65abe2456d7bfa40cfbfaafcbd7b47529");
        log.error("获取的数据 {}", list);
        return R.ok().put("data", "l");
    }


    @Data
    public static class YiDongDTO {
        private String fileName;
        private String path;

    }


}
